package samples.java.json.gson;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.util.Date;
import java.util.HashMap;

import lombok.extern.slf4j.Slf4j;
import samples.java.json.gson.bean.User;

/**
 * @author wang.yuchuan
 * @date 2018/1/31
 */
@Slf4j
public class ObjGsonSamples {

    // null属性也序列化
    public void serializeNulls() {
        User user = new User();
        user.setId(1);

        // 默认配置的Gson
        Gson gson = new Gson();
        // 默认情况下, Gson不序列化值为Null的属性
        String userJsonStr = gson.toJson(user);
        // userJsonStr: {"id":1},
        log.info("userJsonStr: {}", userJsonStr);

        Gson nullGson = new GsonBuilder()
            .serializeNulls() // 序列化值为null的属性
            .create();
        userJsonStr = nullGson.toJson(user);
        // userJsonStr: {"id":1,"name":null,"age":null}
        log.info("userJsonStr: {}", userJsonStr);
    }

    public void serializeDate() {
        User user = new User();
        user.setRegisterTime(new Date());

        Gson defaultGson = new Gson();
        String defaultGsonStr = defaultGson.toJson(user);
        // defaultGsonStr: {"registerTime":"Jan 31, 2018 5:52:47 PM"}
        log.info("defaultGsonStr: {}", defaultGsonStr);

        Gson datetimeGson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd HH:mm:ss") // 时间转化为特定格式
            .create();
        String datetimeGsonStr = datetimeGson.toJson(user);
        // {"registerTime":"2018-01-31 17:54:17"}
        log.info("日期格式化后: {}", datetimeGsonStr);
    }

    public void serializeName() {
        User user = new User();
        user.setBirthday(new Date());
        user.setProperties(new HashMap<String, String>());
        user.getProperties().put("key1", "value1");

        String strJson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd HH:mm:ss")
            .create()
            .toJson(user);
        log.info("@SerializedName注解: {}", strJson);
    }

    public void exposeSerialize() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setRegisterTime(new Date());
        user.setAge(12);

        String strJson = new GsonBuilder()
            .excludeFieldsWithoutExposeAnnotation() //不导出实体中没有用@Expose注解的属性
            .setPrettyPrinting() //对json结果格式化.
            .create()
            .toJson(user);
        log.info("{}", strJson);
    }

    public void mapKeySerialize() {
        User user = new User();
        user.setComplexProperties(new HashMap<User, Integer>());

        User userkey = new User();
        userkey.setId(2);

        user.getComplexProperties().put(userkey, 2);

        String jsonStr = new GsonBuilder()
            .enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式
            .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.
            .setVersion(1.0) //有的字段不是一开始就有的,会随着版本的升级添加进来,那么在进行序列化和返序列化的时候就会根据版本号来选择是否要序列化.
//@Since(版本号)能完美地实现这个功能.还的字段可能,随着版本的升级而删除,那么
//@Until(版本号)也能实现这个功能,GsonBuilder.setVersion(double)方法需要调用.
            .create()
            .toJson(user);
        log.info("{}", jsonStr);
    }

    public static void main(String[] args) {
        ObjGsonSamples objGsonSamples = new ObjGsonSamples();
        objGsonSamples.serializeNulls();
        objGsonSamples.serializeDate();
        objGsonSamples.serializeName();
        objGsonSamples.exposeSerialize();
        objGsonSamples.mapKeySerialize();
    }
}
